---
title: createAI
layout:
  toc: false
---

import { Tabs, Tab } from 'nextra-theme-docs';

# createAI

## `createAI`

`createAI` creates a new `ai/rsc` instance.

## Parameters

### `initialAIState`: [`AIState`](/docs/concepts/ai-rsc#aistate)

`AIState` is a JSON representation of all the context the LLM needs to read. Usually for a chat app, `AIState` contains the textual conversation history between the user and the assistant. It can also be used to store other values and information such as a `createdAt` field for each message, or a `chatId` field besides all the messages.
`AIState` by default, can be accessed/modified on both Server and Client, so the values must be serializable.

### `initialUIState`: [`UIState`](/docs/concepts/ai-rsc#uistate)

`UIState` is what the application uses to display the UI. It is a client-side state (very similar to `useState`) and contains data and UI elements returned by the LLM and your Server Actions. Unlike `AIState`, `UIState` can only be accessed on the client,
but this means that it can contain non-serializable values such as functions and React nodes.

## Returns

The method returns an `<AI>` context provider that can be used to wrap the parts of your tree that use
the client-side hooks [`useAIState`](./use-ai-state) and [`useUIState`](./use-ui-state).

## Example

### Server-Side Setup

<Tabs items={['Next.js (App Router)']}>
  <Tab>
    We use `createAI` to initialize an `ai/rsc` instance on the server.

    ```tsx filename="app/action.tsx" {5-11}
    import 'server-only'

    import { createAI } from "ai/rsc";

    export const AI = createAI({
      actions: {
        submitUserMessage,
      },
      initialUIState: [],
      initialAIState: [],
    });
    ```

  </Tab>
</Tabs>

### Client-Side Setup

<Tabs items={['Next.js (App Router)']}>
  <Tab>
    The `ai/rsc` instance is then available to the client through the `<AI/>` context provider.

    ```tsx filename="app/layout.tsx" {11-13}
    import { AI } from "./action";

    export default function RootLayout({
      children,
    }: Readonly<{
      children: React.ReactNode;
    }>) {
      return (
        <html lang="en">
          <body>
            <AI>
              {children}
            </AI>
          </body>
        </html>
      );
    }

    export const runtime = "edge";
    ```

  </Tab>
</Tabs>
